#include "stdafx.h"
#include "wf_polylineappend.h"



WF_PolylineAppend::WF_PolylineAppend(PF_Container& container,
	PF_GraphicView& graphicView)
	:WF_DrawPolyline(container, graphicView) {}

QAction* WF_PolylineAppend::createGUIAction(LX_Define::ActionType /*type*/, QObject* /*parent*/) {
	QAction* action = new QAction(tr("A&ppend node"), NULL);
	action->setShortcut(QKeySequence());
	action->setStatusTip(tr("Append polyline's node"));
	return action;
}

void WF_PolylineAppend::trigger() {

	PF_DEBUG->print("PF_ActionPolylineAppend::trigger()");

	PF_PreviewActionInterface::trigger();

	if (polyline==NULL) {
		return;
	}

	// add the entity
	//PF_Polyline* polyline = new PF_Polyline(container, data);
	polyline->setLayerToActive();
	polyline->setPenToActive();
	container->addEntity(polyline);

	// upd. undo list:
	if (document!=NULL) {
		document->startUndoCycle();
                //   need to decide on how to handle undy cycles
                // originalPolyline->setUndoState(true);
		document->addUndoable(originalPolyline);
		document->addUndoable(polyline);
                document->endUndoCycle();
	}

	// upd view
	deleteSnapper();
	graphicView->moveRelativeZero(PF_Vector(0.0,0.0));
	graphicView->deleteEntity(originalPolyline);
	graphicView->drawEntity(polyline);
	graphicView->moveRelativeZero(polyline->getEndpoint());
	drawSnapper();
	PF_DEBUG->print("PF_ActionDrawPolyline::trigger(): polyline added: %d",
					polyline->getId());

	polyline = NULL;
}


void WF_PolylineAppend::mouseReleaseEvent(QMouseEvent* e) {
        if (e->button()==Qt::LeftButton) {
		if (getStatus()==SetStartpoint) {
			originalPolyline = (PF_Polyline*)catchEntity(e);
			if (originalPolyline==NULL) {
				PF_DIALOGFACTORY->commandMessage(tr("No Entity found."));
			} else if (originalPolyline->rtti()!=LX_Define::EntityPolyline) {
				PF_DIALOGFACTORY->commandMessage(
					tr("Entity must be a polyline."));
			} else {
				PF_Vector clickCoord = snapPoint(e);
				PF_Entity* entFirst = ((PF_Polyline*)originalPolyline)->firstEntity();
				PF_Entity* entLast = ((PF_Polyline*)originalPolyline)->lastEntity();
				double dist = graphicView->toGraphDX(snapRange)*0.9;
				PF_Entity* nearestSegment = originalPolyline->getNearestEntity( PF_Vector(graphicView->toGraphX(e->x()),
									graphicView->toGraphY(e->y())), &dist, LX_Define::ResolveNone);
				polyline = (PF_Polyline*)originalPolyline->clone();
				prepend = false;
				if (nearestSegment == entFirst){
					prepend = true;
					point = entFirst->getNearestEndpoint(clickCoord, &dist);
				}else if (nearestSegment == entLast){
					point = entLast->getNearestEndpoint(clickCoord, &dist);
				}else{
					PF_DIALOGFACTORY->commandMessage(
						tr("Click somewhere near the beginning or end of existing polyline."));
				}
			}
		}
		PF_CoordinateEvent ce(snapPoint(e));
		coordinateEvent(&ce);
        } else if (e->button()==Qt::RightButton) {
		if (getStatus()==SetNextPoint) {
			trigger();
		}
		// deletePreview();
		//clearPreview();
		deleteSnapper();
		init(getStatus()-1);
	}
}

void WF_PolylineAppend::coordinateEvent(PF_CoordinateEvent* e) {
	if (e==NULL) {
		return;
	}

	PF_Vector mouse = e->getCoordinate();

	switch (getStatus()) {
	case SetStartpoint:
		history.clear();
                history.append(point);
		bHistory.clear();
                bHistory.append(0.0);
		start = point;
		setStatus(SetNextPoint);
		graphicView->moveRelativeZero(point);
		updateMouseButtonHints();
		break;

	case SetNextPoint:
		graphicView->moveRelativeZero(mouse);
		point = mouse;
                history.append(mouse);
                bHistory.append(0.0);
                if (polyline==NULL) {
			polyline = new PF_Polyline(container, data);
			polyline->addVertex(start, 0.0, prepend);
		}
		if (polyline!=NULL) {
			polyline->addVertex(mouse, 0.0, prepend);
//			polyline->setEndpoint(mouse);
			if (polyline->count()==1) {
				polyline->setLayerToActive();
				polyline->setPenToActive();
				container->addEntity(polyline);
			}
			//   (can be deleted) deletePreview();
			//clearPreview();
			deleteSnapper();
			graphicView->drawEntity(polyline);
			drawSnapper();
		}
		//trigger();
		//data.startpoint = data.endpoint;
		updateMouseButtonHints();
		//graphicView->moveRelativeZero(mouse);
		break;

	default:
		break;
	}
}

void WF_PolylineAppend::updateMouseButtonHints() {
	switch (getStatus()) {
	case SetStartpoint:
		PF_DIALOGFACTORY->updateMouseWidget(tr("Specify the polyline somewhere near the beginning or end point"),
						tr("Cancel"));
		break;
	case SetNextPoint: {
                        QString msg = "";

                        if (history.size()>=3) {
				msg += PF_COMMANDS->command("close");
				msg += "/";
			}
                        if (history.size()>=2) {
				msg += PF_COMMANDS->command("undo");
			}

                        if (history.size()>=2) {
				PF_DIALOGFACTORY->updateMouseWidget(
					tr("Specify next point or [%1]").arg(msg),
					tr("Back"));
			} else {
				PF_DIALOGFACTORY->updateMouseWidget(
					tr("Specify next point"),
					tr("Back"));
			}
		}
		break;
	default:
		PF_DIALOGFACTORY->updateMouseWidget("", "");
		break;
	}
}
// EOF
